/*
 * Copyright (c) 2014 pkzd/1.0, 颜文泽(robin)
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     1 Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     2 Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef MC_FS_H
#define MC_FS_H

#define S_IFMT  00170000
	#define S_IFLNK 0120000      
	#define S_IFREG 0100000       
	#define S_IFBLK 0060000        
	#define S_IFDIR 0040000        
	#define S_IFCHR 0020000    
#define S_ISLNK(m)      (((m) & S_IFMT) == S_IFLNK)
#define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)
#define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)
#define S_ISCHR(m)      (((m) & S_IFMT) == S_IFCHR)
#define S_ISBLK(m)      (((m) & S_IFMT) == S_IFBLK)
#define	S_ISUID	0004000			
#define	S_ISGID	0002000			
#define	S_IRWXU	0000700			
	#define	S_IRUSR	0000400			
	#define	S_IWUSR	0000200			
	#define	S_IXUSR	0000100		
#define	S_IRWXG	0000070			
	#define	S_IRGRP	0000040			
	#define	S_IWGRP	0000020			
	#define	S_IXGRP	0000010			
#define	S_IRWXO	0000007			
	#define	S_IROTH	0000004			
	#define	S_IWOTH	0000002			
	#define	S_IXOTH	0000001	

#define NADDR		13 
#define FS_NBFREE       140 
#define FS_NIFREE       100 
#define FS_MAGIC 	0x2024
#define FS_BGRPSZ	101
#define BLKSIZ		1024	
#define ROOTINO 	1	
#define DIRSIZ  	28	
#define NDIRENT 	32 	
#define NIOPB		12	
#define NRSVSCT		31	
#define SPBSIZ		1	

#define MINOR(x)	((x) & 0xfffff)
#define MAJOR(x)	(((x) >> 20) & 0xfff)
#define MAKEDEV(x, y)	(((x) << 20) | y)

struct inode{
	int	i_mode;
	int	i_nlink;
	int	i_uid;
	int	i_gid;
	int	i_size;
	int	i_atime;
	int	i_mtime;
	int	i_ctime;
	int	i_addr[NADDR];
};

struct filsys{
	int	s_magic;
	int	s_isize;
	int	s_ssize;
	int	s_fsize;
	int	s_nfree;
	int	s_free[FS_NBFREE];
	int	s_ninode;
	int	s_inode[FS_NIFREE];
	int	s_time;
	char	s_flock;
	char	s_ilock;
	char	s_fmod;
	char	s_ronly;
	char	s_name[32];
};

struct direct{
	int	d_ino;
	char	d_name[DIRSIZ];
};	

int	clrbuf(int fd, int bn);
int     ialloc(int fd, struct filsys *sp);
int	balloc(int fd, struct filsys *sp);
int	bfree(int fd, struct filsys *sp, int bn);
int	bread(int fd, int bn, void *buf, int cnt);
int	bwrite(int fd, int bn, void *buf, int cnt);
int     itrunc(int fd, struct filsys *sp, struct inode *ip);
int	bmap(int fd, struct filsys *sp, struct inode *ip, int bn);
int	iread(int fd, struct filsys *sp, int ino, struct inode *ip);
int	iwrite(int fd, struct filsys *sp, int ino, struct inode *ip);
int     findfile(int fd, struct filsys *sp, struct inode *ip, char *name);
int	log_read(int fd, struct filsys *sp, int bn, void *buf, struct inode *ip, int cnt);
int	log_write(int fd, struct filsys *sp, int bn, void *buf, struct inode *ip, int cnt);
int	ioadd(int fd, struct filsys *sp, int ino, struct inode *ip, void *buf, int cnt);
int	wddir(int fd, struct filsys *sp, struct inode *ip, struct direct *dp, int flag, int ino);
int	mc_link(int fd, struct filsys *sp, char *dest, char *source);
int	mc_mknod(int fd, struct filsys *sp, char *pathname, int mode, int dev);
int	namei(int fd, struct filsys *sp, char *file, char flag, int ino1);
int	isempty(int fd, struct filsys *sp, struct inode *ip);
char 	*have_path(char *path, char *buf);

#endif
